package com.fysports.web.config;

import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.wall.WallFilter;
import com.fysports.web.config.route.BizModuleRoute;
import com.jfinal.config.*;
import com.jfinal.core.JFinal;
import com.jfinal.ext.handler.ContextPathHandler;
import com.jfinal.ext.handler.UrlSkipHandler;
import com.jfinal.ext.interceptor.ExceptionInterceptor;
import com.jfinal.json.JFinalJson;
import com.jfinal.json.JFinalJsonFactory;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.CaseInsensitiveContainerFactory;
import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.plugin.druid.DruidStatViewHandler;
import com.jfinal.plugin.ehcache.EhCachePlugin;
import com.jfinal.render.FreeMarkerRender;
import com.fysports.framework.render.ErrorRenderFactory;
import com.fysports.framework.render.ExpandExceptionRender;
import com.fysports.framework.render.MainRenderFactory;
import com.fysports.web.config.asyn.AsynInitParamCache;
import com.fysports.web.config.asyn.ThreadSystemLog;
import com.fysports.web.config.freemarker.CacheDirective;
import com.fysports.web.config.route.MobileModuleRoute;
import com.fysports.web.config.route.SystemModuleRoute;
import com.fysports.web.controller.plugin.SelectUserPluginController;
import com.fysports.web.event.EventPlugin;
import com.fysports.web.handler.DownRouteHandler;
import com.fysports.web.handler.InitTableDictCacheHandler;
import com.fysports.web.handler.SystemLogHandler;
import com.fysports.web.interceptor.AuthenticationInterceptor;
import com.fysports.web.kit.commons.StringKit;
import com.fysports.web.model.app.AppBanner;
import com.fysports.web.model.app.AppFeedback;
import com.fysports.web.model.system.*;
import com.fysports.web.model.user.BizUser;
import com.fysports.web.model.user.UserAddress;
import com.fysports.web.model.user.UserFavorite;
import com.fysports.web.model.user.UserRank;


/**
 * 系统核心配置文件
 * Created by konbluesky on 14-7-31.
 */
public class AppConfig extends JFinalConfig {

    public void configConstant(Constants me) {
        /* 1.加载Freemarker配置*/
        FreeMarkerRender.setProperties(loadPropertyFile(AppConst.CONFIG_FREEMARKER));
        /* 2.加载系统配置文件，并放入缓存*/
        loadPropertyFile(AppConst.CONFIG_SYSTEM);
        /* 3.指定默认渲染模板类型*/
        //        me.setViewType(ViewType.OTHER);
        me.setMainRenderFactory(new MainRenderFactory());
        /* 4.设置开发模式 调试；非调试*/
        me.setDevMode(getPropertyToBoolean("devMode"));
        /* 5.设置默认编码*/
        me.setEncoding(StringKit.encoding);
        /* 6.设置上传文件大小 20MB*/
        me.setMaxPostSize(20480000);

        /* 6.将sysconfig配置文件中的变量保存*/
        //        paramMap.put(AppConst.SECURITY_IDEAKEY,getProperty(AppConst.SECURITY_IDEAKEY)); //密钥
        //        paramMap.put(AppConst.UPLOAD_REALPATH,getProperty(AppConst.UPLOAD_REALPATH));//文件根目录
        //        paramMap.put(AppConst.UPLOAD_TMPPATH,getProperty(AppConst.UPLOAD_TMPPATH));//临时文件目录
        /*
        * 替换系统系统默认的错误页面render
        * me.setError404View("/WEB-INF/template/404.ftl");
        * me.setError500View("/WEB-INF/template/500.ftl");
        * */
        me.setErrorRenderFactory(new ErrorRenderFactory());
        /*注册自定义freemarker指令，*/
        FreeMarkerRender.getConfiguration().setSharedVariable("_getCache", new CacheDirective());

        /* 7.初始化Weixin配置*/
//        PropKit.use(AppConst.CONFIG_SYSTEM);
//        // ApiConfigKit 设为开发模式可以在开发阶段输出请求交互的 xml 与 json 数据
//        ApiConfigKit.setDevMode(me.getDevMode());

        me.setJsonFactory(new JFinalJsonFactory());
        /**
         * 开发树形结构功能时,组件默认json解析深度15,>15数据为null,此处修改
         */
        JFinalJson.setDefaultConvertDepth(100);
    }


    public void configRoute(Routes me) {

        /* 1.系统基础模块注册 */
        me.add(new SystemModuleRoute());
        //me.add(new WeiXinModuleRoute()); //微信模块

        /* 2.移动API接口注册 */
        //me.add(new APIMobileModelRoute());

        /* 3.业务模块注册*/
        me.add(new BizModuleRoute());
        me.add(new MobileModuleRoute());

        /* 4.其他定制组件注册*/
        me.add("/plugin/s/user_info", SelectUserPluginController.class);    //选择用户控件
    }


    public void configPlugin(Plugins me) {

        ActiveRecordPlugin arp = null;

        // 1.1 配置Druid数据库连接池插件
        String mysql_jdbcUrl = getProperty("db.jdbcUrl").trim();
        String mysql_userName = getProperty("db.user").trim();
        String mysql_passWord = getProperty("db.password").trim();
        DruidPlugin druidPlugin = new DruidPlugin(mysql_jdbcUrl, mysql_userName, mysql_passWord);
        druidPlugin.addFilter(new StatFilter());
        WallFilter wall = new WallFilter();
        wall.setDbType("mysql");
        druidPlugin.addFilter(wall);

        me.add(druidPlugin);
        // 1.2 配置ActiveRecord插件

        arp = new ActiveRecordPlugin(druidPlugin);
        arp.setShowSql(true);               //打印sql
        arp.setContainerFactory(new CaseInsensitiveContainerFactory(true));// 小写
        arp.setDialect(new MysqlDialect()); // 数据库方言

        // 2. 缓存

        me.add(new EhCachePlugin()); // EhCache缓存

        // 3.1 系统表
        arp.addMapping("sys_log", "uuid", SystemLog.class);                               // 日志表
        arp.addMapping("sys_menu", "uuid", SystemMenu.class);                             // 菜单表
        arp.addMapping("sys_dict", "uuid", SystemDict.class);                             // 系统字典
        arp.addMapping("sys_user", "uuid", SystemUser.class);                           // 系统用户
        arp.addMapping("sys_role", "uuid", SystemRole.class);                             // 系统角
        arp.addMapping("sys_role_user", "uuid", SystemUserRole.class);                    // 用户角色
        arp.addMapping("sys_attachment_file", "uuid", SystemAttachmentFile.class);        // 文件

        //3.2 业务用户相关
        arp.addMapping("user", "uuid", BizUser.class);                                // 用户实体
        arp.addMapping("user_rank","uuid", UserRank.class);                           // 用户等级
        arp.addMapping("user_address","uuid", UserAddress.class);                       //用户地址
        arp.addMapping("user_favorite","uuid", UserFavorite.class);                     //用户收藏
//        arp.addMapping("biz_user_favorite","uuid", BizUserFavorite.class);                //用户收藏
        arp.addMapping("app_feedback","uuid", AppFeedback.class);                           //用户反馈
        arp.addMapping("app_banner","uuid", AppBanner.class);                           //banner

        me.add(arp);


//         4. ConfigPlugin
//                ConfigPlugin configPlugin = new ConfigPlugin(".*\\.properties").reload(false);
//                me.add(configPlugin);
//
//         5. JmsPlugin
//        JmsPlugin jmsPlugin=new JmsPlugin();
//        me.add(jmsPlugin);

        // 6. ResidPlugin
//        RedisPlugin rp=new RedisPlugin("default","192.168.0.205");
//        me.add(rp);
        // 7. EventPlugin
        EventPlugin ep=new EventPlugin();
        me.add(ep);

    }


    public void configInterceptor(Interceptors me) {
        /**
         * 注意注册时顺序,即加载顺序;
         */
        // 1.全局异常拦截器
        ExceptionInterceptor ei=new ExceptionInterceptor();
        ei.setDefault(new ExpandExceptionRender());
        me.add(ei);
        // 2.web 权限验证
        me.add(new AuthenticationInterceptor());
        // 3.mobile 权限验证 TODO测试阶段
//        me.add(new MobileAuthenticationInterceptor());

    }


    public void configHandler(Handlers me) {
        //        String excludsrex="/(plugin|js|css|img)/(My97DatePicker|assets|umeditor|).*";
        //TODO 正则表达式需要修改，目标是过滤掉所有静态文件，不包括系统组件plugin
        String excludsrex = "/(plugin|js|css|img|upload)/[^s/].*";
        me.add(new UrlSkipHandler(excludsrex, false));   //静态文件过滤
        me.add(new ContextPathHandler());
        me.add(new DruidStatViewHandler("/druid")); //druid监控
        me.add(new DownRouteHandler());          //下载图片时需要做路由处理
        me.add(new InitTableDictCacheHandler());    //系统全局变量
        me.add(new SystemLogHandler());             //系统日志记录

        //        me.add(new CacheControlHeaderHandler(5));
        //        me.add(new FakeStaticHandler(".vhtml"));
    }


    @Override public void afterJFinalStart() {
        AsynInitParamCache.start();
        ThreadSystemLog.startSaveDBThread();
    }


    @Override public void beforeJFinalStop() {
        AsynInitParamCache.stop();  //停止时间任务
        ThreadSystemLog.setThreadRun(false); //释放日志入库线程
    }


    public static void main(String[] args) {
                JFinal.start("webapp", 80, "/", 5);
    }
}